home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Utilities / GOCR / src / ocr1.cc < prev    next >
C/C++ Source or Header  |  2000-05-23  |  9KB  |  263 lines

  1. // test routines - faster to compile
  2. #include "pgm2asc.h"
  3. #include "stdlib.h"
  4. #include "stdio.h"
  5.  
  6. // for learn_mode/analyze_mode high, with, yoffset, num of pattern_i,
  7. //  - holes (center,radius in relative coordinates) etc. => cluster analyze
  8. // num_hole => min-volume, tolerance border
  9. // pattern:  @@ @. @@
  10. //           .@ @. ..
  11. // regular filter for large resolutions to make edges more smooth (on boxes)
  12. // extra-filter (only if not recognized?)
  13. //   map + same color to (#==change)
  14. //       - anti color
  15. //       . not used
  16. // strongest neighbour pixels (3x3) => directions
  17. // second/third run with more and more tolerance!?
  18.  
  19. struct lobj {    // line-object (for fitting to near lines)
  20.     int x0,y0;    // starting point (left up)
  21.         int x1,y1;      // end point      (right down)
  22.         int mt;        // minimum thickness
  23.     int q;        // quality, overlapp
  24. };
  25.  
  26. struct lobj obj1;
  27.  
  28. // that is the first draft of feature extraction 
  29. // detect main lines and bows
  30. // seems bad implemented, looking for better algorithms
  31. #define MAXL 10
  32. void ocr2(pix b,int cs){
  33.   int x1,y1,x2,y2,l,i,j,xa[MAXL],ya[MAXL],xb[MAXL],yb[MAXL],ll[MAXL];
  34.   for(i=0;i<MAXL;i++)xa[i]=ya[i]=xb[i]=yb[i]=ll[i]=0;
  35.   for(x1=0;x1<b.x;x1++)        // very slowly, but simple to program
  36.   for(y1=0;y1<b.y;y1++)         // brute force
  37.   for(x2=0;x2<b.x;x2++)
  38.   for(y2=y1+1;y2<b.y;y2++)
  39.   {
  40.     if( get_line2(x1,y1,x2,y2,b,cs,100)>99 )
  41.     {  // line ???
  42.       l=(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);  // len
  43.       for(i=0;i<MAXL;i++)
  44.       {  // remove similar lines (same middle point) IMPROVE IT !!!!!! ???
  45.         if(
  46.             abs(x1+x2-xa[i]-xb[i])<1+b.x/2
  47.          && abs(y1+y2-ya[i]-yb[i])<1+b.y/2
  48.          && abs(y1-ya[i])<1+b.y/4
  49.          && abs(x1-xa[i])<1+b.x/4
  50.           )
  51.         {
  52.           if( l>ll[i] )
  53.           {
  54.             for(j=i;j<MAXL-1;j++)
  55.             {  // shift table
  56.               xa[j]=xa[j+1];ya[j]=ya[j+1];
  57.               xb[j]=xb[j+1];yb[j]=yb[j+1];ll[j]=ll[j+1];
  58.             }
  59.             ll[MAXL-1]=0;;
  60.           }
  61.           else break; // forget it if shorter
  62.         }
  63.         if( l>ll[i] ){ // insert if larger
  64.           for(j=MAXL-1;j>i;j--){  // shift table
  65.             xa[j]=xa[j-1];ya[j]=ya[j-1];
  66.             xb[j]=xb[j-1];yb[j]=yb[j-1];ll[j]=ll[j-1];
  67.           }
  68.           xa[i]=x1;ya[i]=y1;xb[i]=x2;yb[i]=y2;ll[i]=l;
  69.           break;
  70.         }
  71.       }
  72.     }
  73.   }
  74.   for(i=0;i<MAXL;i++){
  75.     printf(" %2d %2d %2d %2d %3d\n",xa[i],ya[i],xb[i],yb[i],ll[i]);
  76.   }  
  77. }
  78.  
  79. // here is the test part for new variants (faster compilation) ;)
  80. char ocr1(struct box *box1, pix  b, int cs, int dots){
  81.    pix p=*(box1->p);
  82.    int    d,x,y,x0=box1->x0,x1=box1->x1,y0=box1->y0,y1=box1->y1;    // d=besterror (not used)
  83.    int  dx=x1-x0+1,dy=y1-y0+1;    // size
  84.    char    bc='_',ac='_';        // bestletter
  85.    int hchar,gchar,ad=0;
  86.    
  87.    // out_x(box1);ocr2(b,cs);  // test other engine
  88.    hchar=0;if( 2*y0<=2*box1->m2-(box1->m2-box1->m1) ) hchar=1;
  89.    gchar=0;if( 2*y1>=2*box1->m3+(box1->m4-box1->m3) ) gchar=1;
  90. //      out_b(p,x0,y0,dx,dy,cs);
  91. //      out_x(box1);
  92.    if(dots>5)printf("# hmm, Something was going wrong.\n");
  93.  
  94.    // --- test italic l ---------------------------------------------------
  95.    // if unsure d should be multiplied by 80..90%
  96.    //     _a
  97.    //     /
  98.    //    /
  99.    //   /
  100.    //  |b c
  101.    //   \/
  102.    if(0)
  103.    if(dy>box1->m3-box1->m2)
  104.    for(d=100; dy>dx && dy>4;){     // min 3x4
  105.       int xa,xb;
  106.       if( dots==1 ) break;
  107.       if( num_cross(0, dx-1,dy/2,dy/2,b,cs) != 1
  108.        || num_cross(0, dx-1,dy/4,dy/4,b,cs) != 1 ) break;
  109.       if( num_cross(0, dx-1,dy-1-dy/16,dy-1-dy/16,b,cs) != 2
  110.        && num_cross(0, dx-1,dy-1-dy/ 8,dy-1-dy/ 8,b,cs) != 2 ) break;
  111.       if( loop(b,0,dy-1,dx,cs,0,RI)
  112.         <=loop(b,0,dy-2,dx,cs,0,RI) ) break; // convex
  113.       // mesure thickness
  114.       if( box1->m2-box1->m1>1 &&  y0>=box1->m2 ) break;
  115.       if( 2*y1<box1->m2+box1->m3 ) break;
  116.       if( 2*y1>box1->m4+box1->m3 ) break;
  117.       out_x(box1);
  118.       xa = dx-1-loop(b,dx-1,     dy/8,dx,cs,0,LE);
  119.       xb =      loop(b,0   ,dy-1-dy/8,dx,cs,0,RI);
  120.       xb+=      loop(b,xb  ,dy-1-dy/8,dx,cs,1,RI)-1;
  121.       printf(" 1");
  122.       if( get_line2(xa  ,dy/8,xb  ,dy-1-dy/8,b,cs,100)<95 ) break;
  123.       printf(" 2");
  124.       //for(y=dy/8;y<7*dy/8;y++){
  125.       //}
  126.       // if( get_line (xa+2,dy/8,xb+2,dy-1-dy/8,b,cs,100)>0  ) break;
  127.       printf("ok");
  128.       bc='l';
  129.       break;
  130.    }
  131.    // --- test l ~italic ---------------------------------------------------
  132.    // if unsure d should be multiplied by 80..90%
  133.    if(dy>box1->m3-box1->m2)
  134.    for(d=100; dy>dx && dy>6;){     // min 3x4
  135.       if( dots==1 ) break;
  136.       int i,j,i1,i2;
  137.       if( num_cross(0, dx-1,dy/2,dy/2,b,cs) != 1
  138.        || num_cross(0, dx-1,dy/4,dy/4,b,cs) != 1 ) break;
  139.       // mesure thickness
  140.       if( box1->m2-box1->m1>1 &&  y0>=box1->m2 ) break;
  141.       for(i1=0,i2=dx,i=1,y=dy/4;y<dy-dy/4 && i;y++){
  142.         j = loop(b,0,y,dx,cs,0,RI);
  143.         j = loop(b,j,y,dx,cs,1,RI);
  144.         if( j>i1 ) { i1=j; } // thickest
  145.         if( j<i2 ) { i2=j; } // thinnest
  146.       }
  147.       if ( i1>2*i2 ) break;
  148.       for(i=dx,j=0,y=0;y<dy/4;y++){
  149.         x=loop(b,dx-1,y,dx,cs,0,LE); if(x-i>1) break; i=x;
  150.         if( num_cross(0,dx-1,y,y,b,cs)==2 ) j=1;
  151.       } if ( y<dy/4 ) break;
  152.       if(j){    // if loop at the upper end, look also on bottom
  153.         for(y=3*dy/4;y<dy;y++){
  154.           if( num_cross(0,dx-1,y,y,b,cs)==2 ) break;
  155.         } if ( y==dy ) break;
  156.       }
  157.  
  158.       // if( get_bw(x0,x1,y0,y1,p,cs,2) == 0 ) break; // unsure !I|
  159.  
  160.       if(dx>3)
  161.       if( get_bw(dx-1,dx-1,0,dy/6,b,cs,3) == 2 )
  162.       if( get_bw(dx-1,dx-1,0,dy/2,b,cs,1) == 1 ) break;
  163.  
  164.       if( get_bw(dx-1,dx-1,dy/4,dy/3,b,cs,3) == 2 ) // large I ???
  165.       if( get_bw(0   ,0   ,dy/4,dy/3,b,cs,3) == 2 )
  166.       if( get_bw(dx-1,dx-1,0   ,0   ,b,cs,1) == 1 )
  167.       if( get_bw(0   ,0   ,0   ,0   ,b,cs,1) == 1 ) break;
  168.       if( get_bw(dx-1,dx-1,dy/2,dy-1,b,cs,3) == 2 ) // r ???
  169.       if( get_bw(0   ,0   ,dy/2,dy-1,b,cs,1) == 1 )
  170.       if( get_bw(dx-1,dx-1,0   ,dy/3,b,cs,1) == 1 )
  171.       if( get_bw(0   ,0   ,0   ,dy/3,b,cs,1) == 1 ) break;
  172.  
  173.       for( y=1;y<12*dy/16;y++ )
  174.       if( num_cross(0, dx-1, y  , y  ,b,cs) != 1     // sure ?
  175.        && num_cross(0, dx-1, y-1, y-1,b,cs) != 1 ) break;
  176.       if( y<12*dy/16 ) break;
  177.  
  178.       if(dx>3){
  179.         for( y=dy/2;y<dy;y++ )
  180.         if( get_bw(dx/4,dx-1-dx/4,y,y,b,cs,1) != 1 ) break;
  181.         if( y<dy ) break;
  182.       }
  183.       // test ob rechte Kante gerade
  184.       for(x=dx,y=b.y-1-dy/4;y>=dy/5;y--){ // rechts abfallende Kante/Knick?
  185.         i=loop(b,b.x-1,y,x1-x0,cs,0,LE);
  186.         if( i-2>=x ) break;
  187.         if( i<x ) x=i;
  188.       }
  189.       if (y>=dy/5 ) break; 
  190.  
  191.       // test ob linke Kante gerade
  192.       for(x=0,y=b.y-1-dy/5;y>=dy/5;y--){ // rechts abfallende Kante/Knick?
  193.         i=loop(b,0,y,x1-x0,cs,0,RI);
  194.         if( i+2<=x ) break;
  195.         if( i>x ) x=i;
  196.       }
  197.       if (y>=dy/5 ) break; 
  198.  
  199.       if( get_bw(x0,x1,y1+1,y1+dy/3,p,cs,1) == 1 ) break; // unsure !l|
  200.       i=loop(b,dx-1,dy/16,dx,cs,0,LE);
  201.       j=loop(b,dx-1,dy/2 ,dx,cs,0,LE);
  202.       if( i>3 && j>3  )
  203.       if( get_bw(dx-1-i/2,dx-1-i/2,0,dy/2,b,cs,1) == 1 ) break; // ~t
  204.  
  205.       i=100;
  206.       if(!hchar) i=i*80/100;
  207.       if( gchar) i=i*80/100;
  208.       if( i>ad ) { ad=i; ac='l'; }
  209.       if( i<100 ) break;
  210.  
  211.       bc='l';
  212.       break;
  213.    }
  214.    // --- test z -------
  215.    for(d=100;dx>3 && dy>3;){     // dy>dx
  216.       int i;
  217.       if( get_bw(0        ,dx/8,dy/2,dy/2,b,cs,1) == 1 ) break;
  218.       if( get_bw(dx-1-dx/8,dx-1,dy/2,dy/2,b,cs,1) == 1 ) break;
  219.       if( get_bw(0        ,dx/4,0   ,dy/4,b,cs,1) != 1 ) break;
  220.       if( get_bw(dx-1-dx/4,dx-1,0   ,dy/4,b,cs,1) != 1 ) break;
  221.       if( get_bw(0        ,dx/4,dy-1-dy/4,dy-1,b,cs,1) != 1 ) break;
  222.       if( get_bw(dx-1-dx/4,dx-1,dy-1-dy/4,dy-1,b,cs,1) != 1 ) break;
  223.       if( get_bw(dx/3,dx-1-dx/3,     dy/2,dy/2,b,cs,1) != 1 ) break;
  224.       if( dx<5 && num_cross(1   ,   1,0,dy-1,b,cs) != 2 ) break;
  225.       if( dx>8 && num_cross(dx/2,dx/2,0,dy-1,b,cs) != 3 ) break;
  226.       if(  num_cross(0   ,dx-1,dy/2+1,dy/2-1,b,cs) != 1 ) break;
  227.       // out_x(box1);
  228.       for( i=1,x=0;x<=dx/2 && i;x++ ){
  229.         if( get_bw(x0+dx/3+x,x0+dx/3+x,y0     ,y0+dy/5,p,cs,1) == 0 ) i=0;
  230.         if( get_bw(x0+dx/8+x,x0+dx/8+x,y1-dy/5,y1     ,p,cs,1) == 0 ) i=0;
  231.       } if( !i ) break;
  232.       // --- line from left down to right up 0003
  233.       for(y=dy/8;y<dy-dy/8;y++){ x=dx-1-dx*y/dy;  // straight line ? 
  234.         if( get_bw(x-dx/8,x+dx/8,y,y,b,cs,1)!=1 ) break; // pixel around ?
  235.       } if(y<dy-dy/8) break;
  236.       if(  loop(b,b.x-1,dy/16,dx,cs,0,LE)
  237.          > loop(b,b.x-1,dy/ 8,dx,cs,0,LE) ) break; // ~2
  238.       x=x0,y=y1;
  239.       turmite(p,x,y,x0,x1,y0,y1,cs,UP,ST); if( y<y1-dy/3 ) break;
  240.       turmite(p,x,y,x0,x1,y0,y1,cs,RI,UP);    //
  241.       if( x<x0+dx/2 || y>y0 ) break;        // upper right edge?
  242.       // --- vertikal line at right end
  243.       x=x1,y=y0+dy/5;
  244.       turmite(p,x,y,x0,x1,y0,y1,cs,LE,ST); if( x<x1-dx/3 ) break;
  245.       turmite(p,x,y,x0,x1,y0,y1,cs,ST,LE); if( x<x1-dx/2 ) break;
  246.       // --- vertikal line at left end
  247.       x=x0,y=y1-dy/5;
  248.       turmite(p,x,y,x0,x1,y0,y1,cs,RI,ST); if( x>x0+dx/3 ) break;
  249.       turmite(p,x,y,x0,x1,y0,y1,cs,ST,RI); if( x>x0+dx/2 ) break;
  250.  
  251.       if( num_hole (x0  , x1  , y0, y1,p,cs) != 0 ) break; 
  252.  
  253.       // test ob rechte Kante ansteigend
  254.       for(x=dx,y=b.y-1-dy/2;y>=dy/4;y--){ // rechts abfallende Kante/Knick?
  255.         i=loop(b,b.x-1,y,x1-x0,cs,0,LE);
  256.         if( i-2>=x ) break; if( i<x ) x=i;
  257.       } if (y>=dy/4 ) break; 
  258.       bc='z'; if( hchar ) bc='Z';
  259.       break;
  260.    }
  261.    return bc;
  262. }
  263.